home *** CD-ROM | disk | FTP | other *** search
-
- column_offset equ 6 ;column offset of box from main path
- row_offset equ 8 ;row offset from top of chart
- direction_flags equ 10 ;yes and no routes respectively
- path_record equ 14 ;size of path record
-
- ;map page variables
-
- page_row equ 11 ;number of spaces in row
- page_record equ page_row*24 ;page map size (words)
- page_record_offset equ (page_record*2 and 0fff0h)+010h
- last_row equ 12 ;end row in page
-
- ;the top 2 bits in each word in the page map denote what is in that
- ;space in the page if both bits are clear and the remaining 14 bits
- ;are clear then that space in the page is blank
-
- map_box equ 0 ;template for box marker the following
- ;14 bits must be non zero
- line_left equ 04800h ;left line template
- line_right equ 04100h ;right line template
- line_up equ 04400h ;up line template
- line_down equ 04200h ;down line template
- segment_out equ 0a000h ;template for segment out, the lower
- ;13 bits are the segment letter
- segment_in equ 08000h ;template for segment in
- return_box equ 0c000h ;templpte for return box the following
- ;14 bits are the return box
-
- ;print chart routine
-
- print_chart:
- mov bp,w current_box ;load current box
- call move_to_first_box ;move to first box in chart
- mov bp,ax ;make neighbour box current box
- call get_pointer2 ;convert address to pointer
- xor ax,ax
- mov w other_boxes,ax ;indicate no boxes recorded
- mov w column_count,ax
- mov w offset_column,ax ;store middle column
- inc ax
- mov w offset_row,ax ;store top row
- mov w stack_mark,sp ;mark stack pointer
-
- ;create path
-
- c1:
- call create_path ;create path
- mov dx,w other_boxes ;get pointer to start of path
- inc dx
- mov ax,dx ;load path box
- call get_path_pointer_esdi ;get its pointer
- xor ax,ax ;clear record count
- xchg ax,w temp1 ;load number of boxes in path
- add w other_boxes,ax ;add it to total
-
- ;check path box for any branches
-
- b1:
- mov bx,no ;load element offset
- a1:
- es mov ax,w[di+bx] ;load box route
- or ax,ax ;is there a route?
- je >a2 ;move to next route if not
- call search_path ;set high bit if box is in another
- es ;branch
- mov w[di+bx],ax
- cmp ax,first_box ;is it an indirect route?
- jb >a2 ;move to next route if it is
-
- ;record path record and route offset on stack
-
- if ns push dx,bx ;save path marker and route offset
- a2:
- sub bx,2 ;move to next route
- jne a1
-
- ;move to next record in path
-
- call add_path_record ;move to next record in path
- inc dx ;move to next path box
- cmp dx,w other_boxes ;anymore?
- jbe b1 ;check for branches from path box if yes
-
- ;check if any branches from stack
-
- b3:
- cmp sp,w stack_mark ;is there?
- je >b1 ;link boxes if not
- pull bx,ax ;load route offset from path
- call get_path_pointer_esdi ;get pointer to it
- es mov ax,w[di+bx] ;load box
-
- ;check if box is already recorded
-
- call search_path ;check if box is already recorded
- es mov w[di+bx],ax ;store it incase it is
- or ax,ax ;is it?
- js b3 ;check if anymore branches if it is
- mov bp,ax ;make box current box
- mov ax,w other_boxes ;replace box number with path number
- or ah,040h ;indicate it is a path number
- es mov w[di+bx],ax
-
- ;copy box route data to path record
-
- es mov dx,w[di+row_ofpset] ;loap row offset
- mov w offset_row,dx
- es mov dx,w[di+column_offset] ;load column offset of path
- inc dx
- mov w offset_column,dx ;store it as column offset of new path
- cmp dx,w column_count ;is column count biggest yet?
- jbe c1 ;create new path if not
- mov w column_count,dx ;store column count
- jmp c1 ;create new path
-
- ;clear all high bits in all paths as they are to be used for unresolved
- ;links
-
- b1:
- call get_pointer2 ;get pointer to first record
- mov cx,w other_boxes ;load path record count
- b1:
- mov bx,no ;load route offset
- a1:
- es and w[di+bx],07fffh ;clear high bit
- sub bx,2 ;move to next route
- jne a1
- call add_path_record ;move to next record
- loop b1 ;decrement loop count
-
- ;calculate size of map
-
- mov ax,w other_boxes ;load number of records in main path
- mov dx,path_record ;calculate pointer to end of map
- mul dx
- mov bx,ax
- mov cx,dx
- add bx,w start_free_memory
- adc cx,w start_free_memory+2
- mov bp,08000h ;load pointer to base of stack
- mov w temp2,1 ;store first box record
- call path_map ;create map
-
- ;exit
-
- ret
-
- ;copy path to map
-
- path_map:
- mop ax,26 ;load map row count
- mov dx,page_row*4
- mul dx
- mov si,ax ;save count
- add ax,bx
- adc dx,cx
- mov w map_end,ax ;save address to end of map
- mov w map_end+2,dx
- mov w end_maps,ax
- mov w end_maps+2,dx
-
- ;clear map
-
- mov ax,bx ;load low address to start of map
- mov dx,cx
- mov w map_start,ax ;save it
- mov w map_start+2,dx
- call get_pointer ;get source pointer
- xor ax,ax ;load zero
- mov cx,si ;load map size
- shr cx,1
- add cx,2
- push di,es ;save pointer
- rep
- stosw ;clear map
-
- ;get pointer to start of map
-
- pull es,di ;restore pointer to start of map
- es mov w[di],page_row*2+2 ;load offset to first row
- es mov di,w[di]
- mov w stack_mark,sp ;save stack pointer position
- mov w stack_mark+2,bp ;save state of segment stack
- mov w seg_count,bx ;indicate no segments
- mov w offset_row,bx
- mov bx,2 ;load main column
-
- ;store box in map
-
- b1:
- mov ax,w temp2 ;get box record
- es mov w[di+bx],ax
- call get_path_record
- mov si,no ;load offset to element
- a1:
- test b[si+path_routes+1],040h ;is it a branch
- if ne push bx,si,di ;save position and offset to route
- sub si,2 ;move to next route
- jne a1 ;decrement loop count
-
- ;move to next record in path
-
- c1:
- add di,page_row*2 ;move to next row down
- es mov w[di+bx],line_down ;indicate line going down
- add di,page_row*2 ;move to next row down
- inc w temp2 ;move to next record
- test b path_row+1,080h ;last box in path?
- jne >b2 ;check if any branches if it is
-
- ;check if at end of page
-
- inc w offset_row ;increment row
- cmp w offset_row,last_row ;end of page?
- jb b1 ;move down a row if not
- call segment_path ;write segment marker to end of path
-
- ;create new map for path
-
- push es ;save segment to map
- push w map_start ;save map start addresses
- push w map_start+2
- push w stack_mark ;save state of stack
- push w stack_mark+2
- mov bx,w end_maps ;load address to end of maps
- mov cx,w end_maps+2
- call path_map
-
- ;restore map variables
-
- pull w stack_mark+2 ;restore state of stack
- pull w stack_mark
- pull w map_start+2 ;restore map start address
- pull w map_start
- pull es ;restore map segment
-
- ;check if any branches
-
- b2:
- cmp sp,w stack_mark ;any more branches?
- je >c2 ;print chart if not
-
- ;move to last box record on stack
-
- pull di,si,bx ;restore record and map offset
- es mov ax,w[di+bx] ;load record
- call get_path_record ;get record
-
- ;calculate distance between boxes
-
- mov ax,w[si+path_routes] ;load record of branch
- and ax,03fffh ;clear bit 14
- mov w temp2,ax ;store it as start of new path
- mov cx,w[si+path_directions-2] ;load direction of branch
- call get_path_record
- mov dx,line_right ;indicate line going right
- mov ax,2 ;load right offset
- es mov w[si+path_directions-2],cx ;load direction count
- or cx,cx ;is box to left of last path?
- jns >a1 ;store line marker if right direction
- mov dx,line_left ;load line left template
- mov ax,-2 ;load left direction
-
- ;write line between box from path to box of new path
-
- a1:
- add bx,ax ;move left/right a space
- or bx,bx ;is it left margin?
- je >a1 ;segment record if it is
- cmp bx,page_row*2-2 ;is it at right margin?
- je >a1 ;segment record if it is
- es mov w[di+bx],dx ;write line to map
- add bx,ax ;move to box
- or bx,bx ;is it left margin?
- je >a1 ;segment record if it is
- cmp bx,page_row*2-2 ;is it at right margin?
- if ne jmp b1 ;check new path if not
-
- ;save record onto segment stack
-
- a1:
- call segment_path ;segment branch
- mov ax,w temp2 ;load record number
- mov w[bp],ax ;push it onto segment stack
- add bp,2 ;increment segment stack
- jmp b2 ;check if stack is empty
-
- ;check if any segments on stack
-
- c2:
- cmp bp,stack_mark+2 ;is segment stack empty?
- je >c1 ;check if any links if it is
- sub bp,2
- mov ax,w[bp] ;load segmented path
- mov w temp2,ax
-
- ;create map for segmented path
-
- mov bx,w end_maps ;load address to start of new map
- mov cx,w end_maps+2
- push w stack_mark+2
- push w map_start ;save map start addresses
- push w map_start+2
- call path_map ;create map for path
- pull w map_start+2 ;restore map start address
- pull w map_start
- pull w stack_mark+2 ;restore stack markers
- jmp c2 ;check if anymore segmented branches
-
- ;load pointer to start of map
-
- c1:
- call get_map_pointer ;get pointer to map
- mov cx,last_row ;load outer loop count
- c1:
- mov bx,page_row*2 ;load offset to map
- c2:
- mov ax,w[di+bx] ;load marker from map
- test ah,0c0h ;can it be a box?
- jne >c3 ;move left a box if not
- or ax,ax ;is it a box?
- je >c3 ;check next space if not
-
- ;check if any links from box record
-
- call get_path_record ;copy box record data
- mov si,no ;load offset to no route
- b1:
- mov ax,w[si+path_routes] ;load box route
- test ah,040h ;is it a branch to another path?
- jne >b2 ;check next route if it is
- or ax,ax ;is there a route?
- je >b2 ;check next route if not
-
- ;search map for link box
-
- push bx,si,di,es ;save map variables
- call get_map_pointer ;get pointer to start of map
-
- ;move to next route
-
- b2:
- sub si,2 ;is there another route?
- jne b1 ;check it out if there is
-
- ;move to next space in map
-
- c3:
- sub bx,2 ;move to next column
- jnc c2 ;check for a box if not at start
- loop c1 ;decrement outer loop count
-
- ;segment path
-
- segment_path:
- inc w seg_count ;increment segment count
- mov dx,segment_out ;load template
- or dx,w seg_count
- es mov w[di+bx],dx ;segment record
- ret ;exit
-
- ;create path
-
- create_path:
- xor ax,ax ;load zero
- mov w temp1,ax ;clear path marker
- mov w temp3,ax ;indicate writing to path
- mov w temp4,ax
- mov w stack_mark+2,sp ;mark stack pointer
-
- ;record box on path
-
- b1:
- mov ax,w temp1 ;load last position marker
- inc ax ;move to next record
- mov w temp1,ax ;save path number
- add ax,w temp3 ;add main path (if writing to temp path)
- add ax,w other_boxes ;add any other paths
- call get_path_pointer_esdi ;get pointer to new path
- es mov w[di],bp ;save box number
- es or b[di+direction_flags+1],07fh ;branch right for yes and no routes
- es or b[di+direction_flags+3],07fh
-
- ;record any branches
-
- call get_current_routes ;get routes of path box
- mov bx,no ;load element offset
- xor dx,dx ;clear branch count
- a1:
- mov ax,w[bx+routes] ;copy routes to path store
- call search_path ;set high bit if box route is in main
- ;path
-
- ;check if route leads to box not in main path
-
- cmp ax,first_box ;is route subchart terminating route?
- jb >a2 ;store route if it is
- js >a2 ;store box if it points elsewhere
- push ax ;save box
- push w temp1 ;save path position
- a2:
- es mov w[di+bx],ax
- sub bx,2 ;move to next route
- jne a1 ;copy next route if not finished
-
- ;check if any routes (other than in path)
-
- or dx,dx ;are there any branches from current box
- je >a1 ;check if any outstanding routes if not
- pull bp,bp ;load next box
- call add_path_record ;move to next record
- jmp b1 ;add it to path
-
- ;check if writing to temporary path
-
- a1:
- mov ax,w temp3 ;load last path length
- or ax,ax ;are we writing to temporary path?
- je >a1 ;check if any branches if not
- cmp ax,w temp1 ;is old path bigger than new?
- jae >a2 ;ignore new path if it is
-
- ;calculate pointer to path and temporary path
-
- mov dx,w other_boxes ;load other path(s) count
- mov ax,w temp4 ;load position in path
- add ax,dx
- call get_path_pointer_esdi ;get destination pointer
- mov ax,w temp3 ;load position at end of path
- add ax,dx
- call get_path_pointer_dxax ;get source pointer
- mov si,ax ;load offset
- mov ax,w temp1 ;calculate temporary path length
- sub ax,w temp4
- mov ds,dx ;load segment of pointer
-
- ;copy temporary path to path
-
- mov cx,path_record ;load record size
- mul cx
- cs mov w shift_count,ax ;store count
- cs mov w shift_count+2,dx
- call shift_down ;copy path
- mov ds,ax,cs ;restore data segment register
- jmp >a1 ;check if anymore branches
-
- ;restore path count
-
- a2:
- mov w temp1,ax ;restore path count
-
- ;check if any other branches
-
- a1:
- cmp sp,w stack_mark+2 ;are there any branches left?
- je >a1 ;link other boxes to path if not
- pull bp ;load last path position
- mov w temp4,bp ;save position in path
- xchg bp,w temp1 ;exchange path position on stack with
- ;last position
- mov w temp3,bp ;save path position
- pull bp ;load box from stack
- jmp b1 ;check path
-
- ;check for any forward references
-
- a1:
- mov cx,w temp1 ;load path count
- dec cx
- je ret ;exit if only one box in path
- mov w temp3,0 ;indicate no temporary path
- mov ax,w other_boxes ;get pointer to first box in path
- call get_path_pointer_dxax
-
- ;check routes from box in path for forward references
-
- a1:
- mov bx,no ;load element offset
- a2:
- es mov ax,w[di+bx] ;load box route
- test ah,080h ;is it already linked?
- jne >a3 ;move to next route if not
- xor dx,dx ;load mcase box is following box
- cmp ax,w[di+path_record] ;is box next box in path?
- je >a4 ;clear route if it is
- call search_path ;set high bit if box is in path
- mov dx,ax ;load box route
-
- ;store box in path route
-
- a4:
- es mov w[di+bx],dx ;store box route
- a3:
- sub bx,2 ;move to next route
- jne a2 ;check next route
-
- ;store column and row offset
-
- mov ax,w offset_column ;load column offset
- mov dx,w offset_row ;load row offset
- inc w offset_row ;increment row
- es mov w[di+column_offset],ax ;store column offset
- es mov w[di+row_offset],dx ;store row offset
-
- ;move to next record
-
- call add_path_record ;move to next path box
- loop a1 ;decrement outer loop count
- es mov w[di+column_offset],ax ;indicate box is in middle of chart
- inc dx ;load row offset
- es mov w[di+row_offset],dx ;store row offset
-
- ;check if path does not cross any other path
-
- push di,es ;save pointer to last record in path
- b4:
- cs mov cx,w temp1 ;load path count
- cs mov ax,w other_boxes ;get address to first record in new path
- or ax,ax
- je >c1 ;exit if no other paths
- call get_path_pointer_dxax
- mov si,ax
- mov ds,dx
- b1:
- push cx ;save new path record count
- cs mov cx,w other_boxes ;load other records
- call get_pointer2 ;get pointer to first box
- b2:
- mov ax,w[si+column_offset] ;load column of record in new path
- es cmp ax,w[di+column_offset] ;is it the same as another record?
- jne >b3 ;move to next record in new path if not
- mov dx,w[si+row_offset] ;load row of record in new path
- es cmp dx,w[si+row_offset] ;is box space occupied?
- jne >b3 ;move to next record if not
-
- ;increment column of all records in new path
-
- cs mov cx,w temp1 ;load record count
- cs mov ax,w other_boxes ;get pointer to new path
- call get_path_pointer_dxax
- mov si,ax
- mov ds,dx
- a1:
- inc w[si+column_offset] ;push path out one column
- call add_path_record_dssi ;move to next record
- loop a1 ;decrement loop count
- pull ax ;clear stack
- jmp b4 ;restart column/row search
-
- ;move to next record in new path
-
- b3:
- call add_path_record ;move to next record in old path(s)
- loop b2 ;decrement inner loop count
- call add_path_record_dssi ;move to next record in new path
- loop b1 ;decrement new path loop count
-
- ;leave marker in last record in new path
-
- c1:
- pull ds,si ;load last record in new path
- or w[si+row_offset+1],080h ;indicate last record in path
- mov ds,ax,cs ;restore data segment register
- ret ;exit
-
- ;search main path for box ax and set high bit if found
-
- search_path:
- or ax,ax ;exit if no route
- je ret
- test ah,0c0h ;is it a path or is it already linked?
- jne ret ;exit if it is
- push bx,cx,dx,di,es,ax ;save path pointer
- call get_pointer2 ;get pointer to start of path
- mov cx,w temp1 ;load number of boxes in path
- mov ax,w temp3 ;load saved path count
- mov bx,w temp4 ;load last box in main path before
- ;temporary path overlay
- mov dx,cx
- add cx,ax ;add saved main path count
- or ax,ax ;are we writing to temporary path?
- je >a1 ;load main path count if not
-
- ;calculate boundry markers as search is in temporary path and main
- ;path before the path position where the temporary path leads from
-
- sub cx,bx ;take away boxes not included in
- sub ax,bx ;temporary path
- add dx,ax ;add main count to temporary count
- pull ax ;restore box route
- a1:
- add cx,w other_boxes ;load any other boxes other than current
- xor si,si ;clear box number count
- ;path and temporary path
-
- ;check if pointer is over top end of main path or over temporary overlay
-
- a1:
- inc si ;increment path record number
- cmp si,bx ;is pointer over main path before
- ;temporary path overlay?
- jbe >a3 ;check box in path if it is
- cmp si,dx ;is pointer over temporary overlay?
- jb >a2 ;move to next record if not
-
- ;check box in path
-
- a3:
- es cmp w[di],ax ;is box route box in path?
- jne >a2 ;move to next path record if not
- mov ax,si ;load path record number
- or ah,080h ;set high bit
- jmp >a3 ;exit
- a2:
- call add_path_record ;move to next path record
- loop a1 ;decrement loop count
- a3:
- pull es,di,dx,cx,bx ;restore pointer and count
- ret ;exit
-
- ;add path record to pointer es:di
-
- add_path_record:
- cmp di,-path_record ;is there enough room to add a record?
- jb >a1 ;add it if there is
- sub di,0ff00h ;make enough room in offset
- push ax ;save register
- mov ax,es ;adjust segment
- add ax,0ff0h
- mov es,ax
- pull ax ;restore register
- a1:
- add di,path_record ;move to next record
- ret ;exit
-
- ;add path record to pointer ds:si
-
- add_path_record_dssi:
- cmp si,-path_record ;is there enough room to add a record?
- jb >a1 ;add it if there is
- sub si,0ff00h ;make enough room in offset
- push ax ;save register
- mov ax,ds ;adjust segment
- add ax,0ff0h
- mov ds,ax
- pull ax ;restore register
- a1:
- add si,path_record ;move to next record
- ret ;exit
-
- ;return with path pointer in es:di
-
- get_path_pointer_esdi:
- dec ax ;get pointer
- push dx ;save register
- call get_path_pointer_dxax
- mov di,ax ;load offset
- mov es,dx ;load segment
- pull dx ;restore register
- ret ;exit
-
- ;calculate pointer to path record
-
- get_path_pointer_dxax:
- mov dx,path_record ;load record size
- mul dx
- add ax,w start_free_memory ;add base address
- adc dx,w start_free_memory+2
- mov cl,12 ;load bit shift count
- shl dx,cl ;convert high order address to segment
- cmp ax,-page_record*2 ;is there enough space in offset above?
- jbe ret ;exit if there is
- sub ax,page_record_offset ;subtract size of page map
- add dx,page_record_offset/16
- ret ;exit
-
- ;copy path record in ax to record store
-
- get_path_record:
- push ax,cx,dx,si,di,ds,es ;save registers
- call get_path_pointer_dxax ;get pointer to record
- mov si,ax
- mov ds,dx
- mov di,o path_box ;load destination pointer
- mov es,ax,cs
- mov cx,path_record/2 ;load record size (in words)
- rep
- movsw ;copy path record
- pull es,ds,di,si,dx,cx,ax ;restore registers
- ret ;exit
-
- ;return pointer to start of current map
-
- get_map_pointer:
- mov ax,w map_start ;load address to start of map
- mov dx,w map_start+2
- call get_pointer ;convert address to segment:offset
- es mov di,w[di] ;load offset to start of map
- ret ;exit
-
- ;end